home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / Apple Location Manager / Sources / Sample.c next >
Encoding:
C/C++ Source or Header  |  1997-05-19  |  15.9 KB  |  643 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        Sample.c
  3.  
  4.      Contains:    Location Manager SDK Sample main code...
  5.  
  6.      Version:    ALM SDK 1.0
  7.                  Package:    Location Manager SDK 1.0
  8.  
  9.      Copyright:    © 1984-1997 by Apple Computer, Inc.
  10.                  All rights reserved.
  11.  
  12.      Bugs?:        If you find a problem with this file, use the Apple Bug Reporter
  13.                  stack.  Include the file and version information (from above)
  14.                  in the problem description and send to:
  15.                      Internet:    apple.bugs@apple.com
  16.  
  17. */
  18.  
  19. #include    <ConditionalMacros.h>
  20.  
  21. #if            !GENERATING68K | GENERATINGCFM
  22.     #error        This project MUST be classic 68K!
  23. #endif
  24.  
  25. // -------------------------------------------------------------------------------------
  26.  
  27. // Project Includes...
  28.  
  29. #ifndef        __SAMPLE__
  30. #include    "Sample.h"
  31. #endif        // __SAMPLE__
  32.  
  33. #ifndef        __UTILITIES__
  34. #include    "Utilities.h"
  35. #endif        // __UTILITIES__
  36.  
  37. // SDK Includes...
  38.  
  39. #define        ALM_BASENAME()
  40. #define        ALM_GLOBALS()        GlobalsHandle
  41.  
  42. #ifndef        __LOCATIONMANAGER_K__
  43. #include    <LocationManager.k.h>
  44. #endif        // __LOCATIONMANAGER_K__
  45.  
  46. // MacOS Includes...
  47.  
  48. #ifndef        __COMPONENTS__
  49. #include    <Components.h>
  50. #endif        // __COMPONENTS__
  51.  
  52. #ifndef        __FONTS__
  53. #include    <Fonts.h>
  54. #endif        // __FONTS__
  55.  
  56. #ifndef        __PLSTRINGFUNCS__
  57. #include    <PLStringFuncs.h>
  58. #endif        // __PLSTRINGFUNCS__
  59.  
  60. #ifndef        __RESOURCES__
  61. #include    <Resources.h>
  62. #endif        // __RESOURCES__
  63.  
  64. #ifndef        __TEXTUTILS__
  65. #include    <TextUtils.h>
  66. #endif        // __TEXTUTILS__
  67.  
  68. // -------------------------------------------------------------------------------------
  69.  
  70. // Readability Constants...
  71.  
  72. #define        kInvalidFunction            ((ComponentFunctionUPP) -1)
  73.  
  74. #define        kDefaultINTLresources        NULL
  75. #define        kNoSeconds                    false
  76.  
  77. // -------------------------------------------------------------------------------------
  78.  
  79. // Local prototypes...
  80.  
  81. static Boolean
  82. CallSupported (SInt16 selector);
  83.     // Return true if the specified selector code is one this module supports...
  84. static ComponentResult
  85. HandleComponentManagerCall (ComponentParameters* params, SInt16 selector);
  86.     // Dispatch a component manager call (selector < 0)...
  87. static ComponentResult
  88. HandleLocationManagerCall (ComponentParameters* params, SInt16 selector, 
  89.         Handle globals);
  90.     // Dispatch a Location Manager specific call...
  91.  
  92. // Component prototypes...
  93.  
  94. static pascal ComponentResult
  95. Open (ComponentInstance self);
  96.     // Initialize the modules's global variables, etc...
  97. static pascal ComponentResult 
  98. Close (ComponentInstance self);
  99.     // Deinitialize the modules's global variables...
  100.  
  101. // --------------------------------------------------------------------------------------
  102.  
  103. // Main entry point (interface as expected by component manager)...
  104.  
  105. pascal ComponentResult
  106. main (ComponentParameters* params, Handle storage) {
  107.  
  108.     // We dispatch the calls from here; also, for ALM calls, we'll make sure the
  109.     // current resource fork is ours...
  110.  
  111.     ComponentResult            result;
  112.     SInt16                    selector     = params->what;
  113.     SInt16                    svResFile    = CurResFile ();
  114.  
  115.     if (selector < 0) {
  116.         // Component manager request codes are negative...
  117.         result = HandleComponentManagerCall (params, selector);
  118.     } else {
  119.         // ALM selectors...
  120.         if (storage != NULL) {
  121.             UseResFile ((**(GlobalsHandle) storage).resFile);
  122.         } // if
  123.         result = HandleLocationManagerCall (params, selector, storage);
  124.     } // if
  125.             
  126.     UseResFile (svResFile);
  127.  
  128.     return result;
  129.  
  130. } // main
  131.  
  132. // -------------------------------------------------------------------------------------
  133.  
  134. static Boolean
  135. CallSupported (SInt16 selector) {
  136.  
  137.     Boolean        response;
  138.  
  139.     switch (selector) {
  140.         case kALMGetCurrentSelect:
  141.         case kALMSetCurrentSelect:
  142.         // case kALMEditSettingSelect:
  143.         case kALMCompareSettingSelect:
  144.         case kALMDescribeSettingsSelect:
  145.         case kALMDescribeErrorSelect:
  146.         case kALMImportExportSelect:
  147.             response = true;
  148.             break;
  149.         default:
  150.             response = false;
  151.             break;
  152.     } // switch
  153.  
  154.     return response;
  155.  
  156. } // CallSupported
  157.  
  158. // -------------------------------------------------------------------------------------
  159.  
  160. static ComponentResult
  161. HandleComponentManagerCall (ComponentParameters* params, SInt16 selector) {
  162.  
  163.     ComponentResult            result     = (ComponentResult) noErr;
  164.     ComponentFunctionUPP     func     = NULL;
  165.  
  166.     switch (selector) {
  167.  
  168.         case kComponentOpenSelect:
  169.             func = (ComponentFunctionUPP) Open;
  170.             break;
  171.         case kComponentCloseSelect:
  172.             func = (ComponentFunctionUPP) Close;
  173.             break;
  174.         case kComponentCanDoSelect:
  175.             result = CallSupported (*(SInt16*) params->params);
  176.             break;
  177.         case kComponentVersionSelect:
  178.             result = kModuleVersion;
  179.             break;
  180.         case kComponentRegisterSelect:
  181.             result = false;            // false means "yes, please register me"    
  182.             break;
  183.         case kComponentTargetSelect :
  184.         case kComponentUnregisterSelect :
  185.             result = badComponentSelector;
  186.             break;
  187.             
  188.     } // switch
  189.     
  190.     if (func != NULL) {
  191.         result = CallComponentFunction (params, func);
  192.     } // if
  193.  
  194.     return result;
  195.  
  196. } // HandleComponentManagerCall
  197.  
  198. // -------------------------------------------------------------------------------------
  199.  
  200. static ComponentResult
  201. HandleLocationManagerCall (ComponentParameters* params, SInt16 selector, 
  202.         Handle globals) {
  203.  
  204.     ComponentResult            result     = (ComponentResult) noErr;
  205.     ComponentFunctionUPP     func     = NULL;
  206.  
  207.     switch (selector) {
  208.     
  209.         case kALMGetCurrentSelect:
  210.             func = (ComponentFunctionUPP) GetCurrent;
  211.             break;
  212.         case kALMSetCurrentSelect:
  213.             func = (ComponentFunctionUPP) SetCurrent;
  214.             break;
  215.         case kALMCompareSettingSelect:
  216.             func = (ComponentFunctionUPP) CompareSetting;
  217.             break;
  218.         //case kALMEditSettingSelect:
  219.         //    func = (ComponentFunctionUPP) EditSetting;
  220.         //    break;
  221.         case kALMDescribeSettingsSelect:
  222.             func = (ComponentFunctionUPP) DescribeSettings;
  223.             break;
  224.         case kALMDescribeErrorSelect:
  225.             func = (ComponentFunctionUPP) DescribeError;
  226.             break;
  227.         case kALMImportExportSelect:
  228.             func = (ComponentFunctionUPP) ImportExport;
  229.             break;
  230.         case kALMGetScriptInfoSelect:
  231.             func = (ComponentFunctionUPP) GetScriptInfo;
  232.             break;
  233.         case kALMGetInfoSelect:
  234.             func = (ComponentFunctionUPP) GetInfo;
  235.             break;
  236.         default:
  237.             func = kInvalidFunction;
  238.             break;
  239.             
  240.     } // switch
  241.  
  242.     if (func == kInvalidFunction) {
  243.         result = badComponentSelector;
  244.     } else if (func != NULL) {
  245.         result = CallComponentFunctionWithStorage (globals, params, func);
  246.     } // if
  247.  
  248.     return result;
  249.  
  250. } // HandleLocationManagerCall
  251.  
  252. // -------------------------------------------------------------------------------------
  253.  
  254. static    pascal ComponentResult
  255. Open (ComponentInstance self) {
  256.  
  257.     // Keep the Open routine lightweight, and only fail in the case of dire
  258.     // emergencies that indicate a major problem...
  259.  
  260.     OSErr                err        = noErr;
  261.     GlobalsHandle        globals    = (GlobalsHandle) NewHandle (sizeof (Globals));
  262.     
  263.     if (globals != NULL) {
  264.     
  265.         SetComponentInstanceStorage (self, (Handle) globals);
  266.     
  267.         (**globals).fileCount    = 0;
  268.         (**globals).self         = (Component) self;
  269.         (**globals).resFile        = OpenComponentResFile ((Component) self);
  270.     
  271.         err = ResError ();
  272.     
  273.     } else {
  274.         err = memFullErr;
  275.     } // if
  276.  
  277.     return (ComponentResult) err;
  278.     
  279. } // Open
  280.  
  281. // -------------------------------------------------------------------------------------
  282.  
  283. static    pascal ComponentResult
  284. Close (ComponentInstance self) {
  285.  
  286.     OSErr                err        = noErr;
  287.     GlobalsHandle        globals    = (GlobalsHandle) GetComponentInstanceStorage (self);
  288.  
  289.     if (globals != NULL) {
  290.  
  291.         SInt16        resFile = (**globals).resFile;
  292.  
  293.         if (resFile > 0)    {    
  294.             CloseComponentResFile (resFile);
  295.             (**globals).resFile = 0;
  296.         } // if
  297.  
  298.         DisposeHandle ((Handle) globals);
  299.         SetComponentInstanceStorage (self, NULL);
  300.  
  301.     } // if
  302.  
  303.     return (ComponentResult) err;
  304.     
  305. } // Close
  306.  
  307. // -------------------------------------------------------------------------------------
  308.  
  309. static pascal ComponentResult    
  310. GetCurrent (GlobalsHandle globals, Handle setting) {
  311.  
  312.     OSErr                err        = noErr;
  313.  
  314.     // To get the current settings, we need to go off to the resource and make FSSpecs
  315.     // for all of the files we care about, then read in their settings...
  316.  
  317.     err = ConfirmFSSpecs (globals);
  318.  
  319.     if (err == noErr) {
  320.         err = ReadSetting (globals, (SettingHandle) setting);
  321.     } // if
  322.  
  323.     return (ComponentResult) err;
  324.  
  325. } // GetCurrent
  326.  
  327. // -------------------------------------------------------------------------------------
  328.  
  329. static pascal ComponentResult
  330. SetCurrent (GlobalsHandle globals, Handle setting, ALMRebootFlags* flags) {
  331.  
  332.     OSErr                err                = noErr;
  333.     Handle                tempSetting        = NewHandle (1);
  334.  
  335.     *flags = kALMNoChange;        // Safe value...
  336.  
  337.     // Before we go off and change the setting, see if it's the current setting; if
  338.     // the settings are _not_ the same, we'll assume "kALMAvailableNow" and let
  339.     // UseSetting escalate it, based on any of the specific files...
  340.         
  341.     if (tempSetting != NULL) {
  342.         err = (OSErr) GetCurrent (globals, tempSetting);
  343.         if (err == noErr) {
  344.             Boolean        lookTheSame;
  345.             err = CompareSetting (globals, tempSetting, setting, &lookTheSame);
  346.             if ((err == noErr) && !lookTheSame) {
  347.                 *flags = kALMAvailableNow;
  348.                 err = UseSetting (globals, (SettingHandle) setting, flags);
  349.             } // if
  350.         } // if
  351.     } else {
  352.         err = memFullErr;
  353.     } // if
  354.  
  355.     if (tempSetting != NULL) {
  356.         DisposeHandle (tempSetting);    
  357.     } // if
  358.  
  359.     return (ComponentResult) err;
  360.  
  361. } // SetCurrent
  362.  
  363. // -------------------------------------------------------------------------------------
  364.  
  365. static pascal ComponentResult
  366. CompareSetting (GlobalsHandle globals, Handle setting1, Handle setting2, 
  367.         Boolean* equal) {
  368.  
  369. #ifndef    __SC__
  370. #pragma unused (globals)
  371. #endif    // __SC__
  372.  
  373.     OSErr                err            = noErr;
  374.     SInt8                svState1    = HGetState (setting1);
  375.     SInt8                svState2    = HGetState (setting2);
  376.     SettingPtr            set1;
  377.     SettingPtr            set2;
  378.  
  379.     *equal = true;
  380.  
  381.     // To see if two settings are the same, all we do is compare their dates...
  382.     
  383.     HLock (setting1);
  384.     HLock (setting2);
  385.     
  386.     set1 = (SettingPtr) *setting1;
  387.     set2 = (SettingPtr) *setting2;
  388.     
  389.     do {
  390.     
  391.         UInt32    fileIndex;
  392.         UInt32    fileCount = set1->fileCount;
  393.     
  394.         // If the settings versions are not the same, we have a problem...
  395.         
  396.         if (set1->version != set2->version) {
  397.             *equal = false;
  398.             break;
  399.         } // if
  400.  
  401.         // If the number of files modified is not the same, we have a problem...
  402.     
  403.         if (fileCount != set2->fileCount) {
  404.             *equal = false;
  405.             break;
  406.         } // if
  407.         
  408.         // Now, if the modification dates (or creation dates) changed, we'll take
  409.         // that as a signal 
  410.         
  411.         for (fileIndex = 0; fileIndex < fileCount; fileIndex += 1) {
  412.             if ((set1->fileInfo[fileIndex].dateModified != 
  413.                     set2->fileInfo[fileIndex].dateModified) ||
  414.                     (set1->fileInfo[fileIndex].dateCreated != 
  415.                         set2->fileInfo[fileIndex].dateCreated)) {
  416.                 *equal = false;
  417.                 break;
  418.             } // if
  419.         } // for
  420.         
  421.     } while (false); // Loop once...
  422.     
  423.     HSetState (setting2, svState2);
  424.     HSetState (setting1, svState1);
  425.  
  426.     return (ComponentResult) err;
  427.  
  428. } // CompareSetting
  429.  
  430. // -------------------------------------------------------------------------------------
  431.  
  432. static pascal ComponentResult
  433. EditSetting (GlobalsHandle globals, Handle setting) {
  434.  
  435. #ifndef    __SC__
  436. #pragma unused (globals, setting)
  437. #endif    // __SC__
  438.  
  439.     OSErr                err        = noErr;
  440.  
  441.     // Not implemented or called; not sure what the content of setting is...
  442.  
  443.     return (ComponentResult) err;
  444.  
  445. } // EditSetting
  446.  
  447. // -------------------------------------------------------------------------------------
  448.  
  449. static pascal ComponentResult
  450. DescribeSettings (GlobalsHandle globals, Handle setting, CharsHandle text) {
  451.  
  452.     OSErr                err        = noErr;
  453.     SettingHandle        theSet    = (SettingHandle) setting;
  454.     UInt32                dateMod;
  455.     Str255                dateModStr;
  456.     Str255                timeModStr;
  457.     Str63                firstFileStr;
  458.     Str255                templateStr;
  459.  
  460.     // Not entirely sure how to describe the settings, but we'll take the approach
  461.     // of using the first file name and its modification date as "sufficient" info...
  462.     
  463.     err = ConfirmFSSpecs (globals);
  464.  
  465.     if (err == noErr) {
  466.  
  467.         SInt8        svState;
  468.         UInt8        strSize;
  469.         
  470.         dateMod = (**theSet).fileInfo[0].dateModified;
  471.         
  472.         DateString (dateMod, shortDate,  dateModStr, kDefaultINTLresources);
  473.         TimeString (dateMod, kNoSeconds, timeModStr, kDefaultINTLresources);
  474.         GetIndString (templateStr, kSampleMiscStrRsrcID, kSampleDescribeTemplateIdx);
  475.  
  476.         svState = HGetState ((Handle) globals);
  477.         HLock ((Handle) globals);
  478.         PLstrcpy (firstFileStr, (**globals).theFiles[0].name);
  479.         HSetState ((Handle) globals, svState);
  480.  
  481.         InsParamStr ("\p^0", firstFileStr, templateStr);
  482.         InsParamStr ("\p^1", timeModStr, templateStr);
  483.         InsParamStr ("\p^2", dateModStr, templateStr);
  484.         
  485.         strSize = StrLength (templateStr);
  486.         SetHandleSize ((Handle) text, strSize);
  487.         err = MemError ();
  488.         if (err == noErr) {
  489.             BlockMoveData (&templateStr[1], *text, strSize);
  490.         } // if
  491.     
  492.     } // if
  493.  
  494.     return (ComponentResult) err;
  495.  
  496. } // DescribeSettings
  497.  
  498. // -------------------------------------------------------------------------------------
  499.  
  500. static pascal ComponentResult
  501. DescribeError (GlobalsHandle globals, OSErr lastErr, Str255 errStr) {
  502.  
  503. #ifndef    __SC__
  504. #pragma unused (globals)
  505. #endif    // __SC__
  506.  
  507.     OSErr                err        = noErr;
  508.  
  509.     // We're just going to be very superficial about this, and deal with a very few
  510.     // "plain text" messages only. We could get fancy, and try to be a bit more 
  511.     // descriptive...
  512.  
  513.     if ((lastErr > 0) && (lastErr <= kSampleBiggestKnownIdx)) {
  514.         GetIndString (errStr, kSampleErrStrRsrcID, lastErr);
  515.     } else {
  516.         err = paramErr;    // Get ALM to generate default "error number" text...
  517.     } // if
  518.  
  519.     return (ComponentResult) err;
  520.  
  521. } // DescribeError
  522.  
  523. // -------------------------------------------------------------------------------------
  524.  
  525. static pascal ComponentResult
  526. ImportExport (GlobalsHandle globals, Boolean import, Handle setting, short resRefNum) {
  527.  
  528. #ifndef    __SC__
  529. #pragma unused (resRefNum)
  530. #endif    // __SC__
  531.  
  532.     OSErr                err        = noErr;
  533.  
  534.     // Not a lot of work to do here; but if we are importing _and_ the current settings
  535.     // on the machine match the import, we have a problem in that our mechanism doesn't
  536.     // let us distinguish the new setting properly. It is possible that the user would
  537.     // prefer to overwrite the existing settings, but we won't handle that case...
  538.     
  539.     if (import) {
  540.     
  541.         Handle        tempSetting        = NewHandle (1);
  542.         
  543.         if (tempSetting != NULL) {
  544.             err = (OSErr) GetCurrent (globals, tempSetting);
  545.             if (err == noErr) {
  546.                 Boolean        lookTheSame;
  547.                 err = CompareSetting (globals, tempSetting, setting, &lookTheSame);
  548.                 if ((err == noErr) && lookTheSame) {
  549.                     err = kSampleImportPrefDatesIdx;
  550.                 } // if
  551.             } // if
  552.         } else {
  553.             err = memFullErr;
  554.         } // if
  555.     
  556.         if (tempSetting != NULL) {
  557.             DisposeHandle (tempSetting);    
  558.         } // if
  559.  
  560.     } // if
  561.  
  562.     return (ComponentResult) err;
  563.  
  564. } // ImportExport
  565.  
  566. // -------------------------------------------------------------------------------------
  567.  
  568. static pascal ComponentResult
  569. GetScriptInfo (GlobalsHandle globals, ALMScriptMgrInfo* info) {
  570.  
  571. #ifndef    __SC__
  572. #pragma unused (globals)
  573. #endif    // __SC__
  574.  
  575.     OSErr                err            = noErr;
  576.     INTLinfoHandle        scriptInfo    = NULL;
  577.  
  578.     // We stored this stuff in a resource, so it can be localized easily; we have
  579.     // to do a bit of translation, though, from our resource format to the ALM format...
  580.     
  581.     scriptInfo = (INTLinfoHandle) GetResource (kINTLrsrcType, kINTLrsrcID);
  582.     
  583.     if (scriptInfo != NULL) {
  584.  
  585.         HLock ((Handle) scriptInfo);
  586.         
  587.         info->version         = (**scriptInfo).version;
  588.         info->scriptCode     = (**scriptInfo).scriptCode;
  589.         info->regionCode     = (**scriptInfo).regionCode;
  590.         info->langCode         = (**scriptInfo).langCode;
  591.         info->fontSize         = (**scriptInfo).fontSize;
  592.         GetFNum ((**scriptInfo).fontName, &info->fontNum);
  593.         
  594.         HUnlock ((Handle) scriptInfo);
  595.  
  596.     } else {
  597.         err = ResError ();
  598.     } // if
  599.  
  600.     if (scriptInfo != NULL) {
  601.         ReleaseResource ((Handle) scriptInfo);
  602.     } // if
  603.  
  604.     return (ComponentResult) err;
  605.  
  606. } // GetScriptInfo
  607.  
  608. // -------------------------------------------------------------------------------------
  609.  
  610. static pascal ComponentResult
  611. GetInfo (GlobalsHandle globals, CharsHandle* text, STHandle* style, 
  612.         ModalFilterUPP filter) {
  613.  
  614. #ifndef    __SC__
  615. #pragma unused (globals, filter)
  616. #endif    // __SC__
  617.  
  618.     OSErr                err        = noErr;
  619.  
  620.     // This code is pretty cookie-cutter, unless you want to make it context-
  621.     // sensitive...
  622.  
  623.     do {
  624.     
  625.         *text = (CharsHandle) Get1Resource ('TEXT', kGetInfoRsrcID);
  626.         err = ResError ();
  627.         if (err != noErr) {
  628.             break;
  629.         } // if
  630.         *style = (STHandle) Get1Resource ('styl', kGetInfoRsrcID);
  631.         err = ResError ();
  632.         if (err != noErr) {
  633.             break;
  634.         } // if
  635.         DetachResource ((Handle) *text);
  636.         DetachResource ((Handle) *style);
  637.     
  638.     } while (false);    // execute once...
  639.     
  640.     return (ComponentResult) err;
  641.  
  642. } // GetInfo
  643.